package com.itheima.service.impl;

import com.itheima.common.vo.*;
import com.itheima.mapper.MemberDao;
import com.itheima.mapper.OrderDao;
import com.itheima.pojo.Member;
import com.itheima.pojo.Order;
import com.itheima.service.ReportService;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;
    @Value("classpath:templates/report_template.xlsx")
    private Resource resource;
    @Autowired
    private HttpServletResponse response;

    /**
     * 会员统计图表数据
     * @return
     */
    @Override
    public MemberReportVo getMemberReport() {
        LocalDate now = LocalDate.now();
        List<String> lastDays = new ArrayList<>();
        ArrayList<Integer> memberCount = new ArrayList<>();

        // 获取往前12个月（不包括当月）每个月的最后一天
        for (int i = 1; i <= 12; i++) {
            LocalDate lastDayOfMonth = now.minusMonths(i).with(TemporalAdjusters.lastDayOfMonth());
            // 获取该月的会员数
            Integer count = memberDao.getMemberCountByDate(lastDayOfMonth);
            String formattedDate = lastDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));
            lastDays.add(formattedDate);
            memberCount.add(count);
        }
        MemberReportVo memberReportVo = new MemberReportVo(lastDays, memberCount);

        return memberReportVo;
    }

    /**
     * 套餐统计图表数据
     * @return
     */
    @Override
    public SetmealStatistic getSetmealReport() {
        List<String> setmealNames = new ArrayList<>();
        List<SetmealReport> setmealCount = orderDao.getSetmealCountAndName();
        for (SetmealReport setmealReport : setmealCount) {
            setmealNames.add(setmealReport.getName());
        }
        SetmealStatistic setmealStatistic = new SetmealStatistic(setmealNames, setmealCount);
        return setmealStatistic;
    }

    /**
     * 运营数据统计
     *
     * @return
     */
    @Override
    public BusinessReportData getBusinessReportData() {
        BusinessReportData businessReportData = new BusinessReportData();
        LocalDate now = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 格式化日期为字符串
        String formattedDate = now.format(formatter);
        // 获取本月第一天
        LocalDate firstDayOfMonth = now.with(TemporalAdjusters.firstDayOfMonth());
        // 获取本周第一天（假设一周从周一算起）
        LocalDate firstDayOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));

        //处理订单的数量
        //获取当天的就诊数量
        Integer todayVisitsNumber = orderDao.getCountByDateAndStatus(now, now, Order.ORDERSTATUS_YES);
        //获取当天的预约数量
        Integer todayOrderNumber = orderDao.getCountByDateAndStatus(now, now, null);
        //获取本周的就诊数量
        Integer thisWeekVisitsNumber = orderDao.getCountByDateAndStatus(firstDayOfWeek, now, Order.ORDERSTATUS_YES);
        //获取本周的预约数量
        Integer thisWeekOrderNumber = orderDao.getCountByDateAndStatus(firstDayOfWeek, now, null);
        // 获取本月的就诊数量
        Integer thisMonthVisitsNumber = orderDao.getCountByDateAndStatus(firstDayOfMonth, now, Order.ORDERSTATUS_YES);
        //获取本月的预约数量
        Integer thisMonthOrderNumber =  orderDao.getCountByDateAndStatus(firstDayOfMonth, now, null);

        //处理会员的数量
        // 获取当天的会员数量
        Integer todayNewMember = memberDao.getCountByDate(now, now);
        // 获取本周的会员数量
        Integer thisWeekNewMember = memberDao.getCountByDate(firstDayOfWeek, now);
        // 获取本月的会员数量
        Integer thisMonthNewMember = memberDao.getCountByDate(firstDayOfMonth, now);
        // 获取总会员数量
        Integer totalMember = memberDao.getMemberList().size();

        //处理热门套餐属性
        List<SetmealReport> setmealCountAndName = orderDao.getSetmealCountAndName();
        Integer setmeal_count = 0;
        for (SetmealReport setmealReport : setmealCountAndName) {
            setmeal_count += setmealReport.getValue();
        }
        ArrayList<HotSetmeal> hotSetmeals = new ArrayList<>();
        for (SetmealReport setmealReport : setmealCountAndName) {
            double temp = setmealReport.getValue() * 1.0 / setmeal_count;
            BigDecimal bigDecimal = new BigDecimal(temp).setScale(1, RoundingMode.HALF_UP);
            double proportion = bigDecimal.doubleValue();
            HotSetmeal hotSetmeal = new HotSetmeal(proportion, setmealReport.getName(), setmealReport.getValue());
            hotSetmeals.add(hotSetmeal);
        }

        //整合所有的数据
        businessReportData = new BusinessReportData(todayVisitsNumber, formattedDate, todayNewMember, thisWeekVisitsNumber, thisMonthVisitsNumber, hotSetmeals, thisMonthNewMember, thisWeekNewMember, totalMember, thisMonthOrderNumber, todayOrderNumber, thisWeekOrderNumber);

        return businessReportData;
    }

    /**
     * 导出运营数据统计
     */
    @Override
    public void exportBusinessReport() throws IOException {
        BusinessReportData businessReportData = getBusinessReportData();
        InputStream inputStream = resource.getInputStream();
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        XSSFSheet sheet = workbook.getSheet("Sheet1");
        XSSFRow row2 = sheet.getRow(2);
        row2.getCell(5).setCellValue(businessReportData.getReportDate());
        XSSFRow row4 = sheet.getRow(4);
        row4.getCell(5).setCellValue(businessReportData.getTodayNewMember());
        row4.getCell(7).setCellValue(businessReportData.getTotalMember());
        XSSFRow row5 = sheet.getRow(5);
        row5.getCell(5).setCellValue(businessReportData.getThisWeekNewMember());
        row5.getCell(7).setCellValue(businessReportData.getThisMonthNewMember());
        XSSFRow row7 = sheet.getRow(7);
        row7.getCell(5).setCellValue(businessReportData.getTodayOrderNumber());
        row7.getCell(7).setCellValue(businessReportData.getTodayVisitsNumber());
        XSSFRow row8 = sheet.getRow(8);
        row8.getCell(5).setCellValue(businessReportData.getThisWeekOrderNumber());
        row8.getCell(7).setCellValue(businessReportData.getThisWeekVisitsNumber());
        XSSFRow row9 = sheet.getRow(9);
        row9.getCell(5).setCellValue(businessReportData.getThisMonthOrderNumber());
        row9.getCell(7).setCellValue(businessReportData.getThisMonthVisitsNumber());
        for (int i = 0; i < businessReportData.getHotSetmeal().size(); i++) {
            XSSFRow row = sheet.getRow(12 + i);
            row.getCell(4).setCellValue(businessReportData.getHotSetmeal().get(i).getName());
            row.getCell(5).setCellValue(businessReportData.getHotSetmeal().get(i).getSetmeal_count());
            row.getCell(6).setCellValue(businessReportData.getHotSetmeal().get(i).getProportion());
        }
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=report.xlsx");
        workbook.write(response.getOutputStream());



    }


}
